package com.sojson.util.async.interfaces;

import static com.sojson.util.async.PageHandleUtil.IS_NEXT_PAGE;
import static com.sojson.util.async.PageHandleUtil.ORDER_BY_COLUMN_DEFAULT;

import java.util.List;

import com.sojson.config.exception.TransException;
import com.sojson.util.StringUtil;
import com.sojson.util.async.PageHandleUtil;

/**
 * 列表处理器抽象类
 * 
 * @author liu
 * @date 2021-08-15
 */
public abstract class ListHandle<T> {

    /** 分页处理器 */
    private PageHandle<T> pageHandle;

    /**
     * 构造方法
     */
    public ListHandle() {
        setPageHandle(PageHandleUtil.getPageHandleThis());
    }

    /**
     * 构造方法
     * 
     * @param isNaxtPage    后面查询的数据是否是下一页的数据(true:一直查下一页的数据:false:一直查当前页的数据)
     */
    public ListHandle(boolean isNaxtPage) {
        this(ORDER_BY_COLUMN_DEFAULT, isNaxtPage);
    }

    /**
     * 构造方法
     * 
     * @param orderByColumn 查询数据的排序字段
     */
    public ListHandle(String orderByColumn) {
        this(orderByColumn, IS_NEXT_PAGE);
    }

    /**
     * 构造方法
     * 
     * @param orderByColumn 查询数据的排序字段
     * @param isNaxtPage    后面查询的数据是否是下一页的数据(true:一直查下一页的数据:false:一直查当前页的数据)
     */
    public ListHandle(String orderByColumn, boolean isNaxtPage) {
        if (isNaxtPage) {
            setPageHandle(PageHandleUtil.getPageHandleNext(orderByColumn));
            return;
        }

        // 不修改分页数据,还是获取当前页的数据
        setPageHandle(PageHandleUtil.getPageHandleThis(orderByColumn));
    }

    /**
     * 构造方法
     * 
     * @param list  数据
     */
    public ListHandle(List<T> list) {
        this(list, IS_NEXT_PAGE);
    }

    /**
     * 构造方法
     * 
     * @param list          数据
     * @param isNaxtPage    后面查询的数据是否是下一页的数据(true:一直查下一页的数据:false:一直查当前页的数据)
     */
    public ListHandle(List<T> list, boolean isNaxtPage) {
        this(list, ORDER_BY_COLUMN_DEFAULT, isNaxtPage);
    }

    /**
     * 构造方法
     * 
     * @param list          数据
     * @param orderByColumn 查询数据的排序字段
     */
    public ListHandle(List<T> list, String orderByColumn) {
        this(list, orderByColumn, IS_NEXT_PAGE);
    }

    /**
     * 构造方法
     * 
     * @param list          数据
     * @param orderByColumn 查询数据的排序字段
     * @param isNaxtPage    后面查询的数据是否是下一页的数据(true:一直查下一页的数据:false:一直查当前页的数据)
     */
    public ListHandle(List<T> list, String orderByColumn, boolean isNaxtPage) {
        if (isNaxtPage) {
            setPageHandle(PageHandleUtil.getPageHandleNext(list, orderByColumn));
            return;
        }

        // 不修改分页数据,还是获取当前页的数据
        setPageHandle(PageHandleUtil.getPageHandleThis(list, orderByColumn));
    }

    /**
     * 构造方法
     */
    public ListHandle(PageHandle<T> pageHandle) {
        setPageHandle(pageHandle);
    }

    /**
     * 执行方法
     */
    public void start() {
        if (StringUtil.isBlankObject(pageHandle.getPageNum())) {
            throw new TransException("第几页不能为空");
        }
        if (StringUtil.isBlankObject(pageHandle.getPageSize())) {
            throw new TransException("每页显示记录数不能为空");
        }
        if (StringUtil.isBlankObject(pageHandle.getIsPage())) {
            throw new TransException("是否分页不能为空");
        }

        // 第一次执行(用来获取分页数据)
        // 获取数据
        List<T> runInit = this.runInit();
        // 执行
        this.run(runInit);

        // 设置剩下要执行的次数
        Integer runNum = pageHandle.getRunNum();
        if (StringUtil.isBlankObject(runNum)) {
            throw new TransException(
                "执行次数不能为空,请重写初始化分页数据的逻辑{@link com.sojson.util.async.interfaces.ListHandle#runInit()}");
        }
        // 执行剩下的
        for (int i = 1; i < runNum; i++) {
            this.run(runInit);
        }
    }

    /**
     * 执行方法(执行次数可动态修改)
     */
    public void startRunNum() {
        if (StringUtil.isBlankObject(pageHandle.getPageNum())) {
            throw new TransException("第几页不能为空");
        }
        if (StringUtil.isBlankObject(pageHandle.getPageSize())) {
            throw new TransException("每页显示记录数不能为空");
        }
        if (StringUtil.isBlankObject(pageHandle.getIsPage())) {
            throw new TransException("是否分页不能为空");
        }

        // 第一次执行(用来获取分页数据)
        // 获取数据
        List<T> runInit = this.runInit();
        // 执行
        this.run(runInit);

        // 设置剩下要执行的次数
        Integer runNum = pageHandle.getRunNum();
        if (StringUtil.isBlankObject(runNum)) {
            pageHandle.setRunNum(1);
        }
        // 执行剩下的
        for (int i = 0; i < pageHandle.getRunNum(); i++) {
            this.run(runInit);
        }
    }

    /**
     * 第一次执行(用来获取分页数据)
     * 
     * @return
     */
    public List<T> runInit() {
        // 获取数据
        List<T> list = this.getList();
        // 初始化分页数据
        pageHandle.init(list);
        return list;
    }

    /**
     * 获取列表
     */
    public abstract List<T> getList();

    /**
     * 方法实现(注意处理分页逻辑)
     * 
     * @param list  获取的列表
     */
    public abstract void run(List<T> list);

    /** 获取 分页处理器 */
    public PageHandle<T> getPageHandle() {
        return pageHandle;
    }

    /** 设置 分页处理器 */
    public void setPageHandle(PageHandle<T> pageHandle) {
        this.pageHandle = pageHandle;
    }

}